package com.vcc.service.impl;

import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryChain;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.vcc.core.exception.NotFoundException;
import com.vcc.core.exception.ProgramException;
import com.vcc.core.util.RegexUtil;
import com.vcc.data.entity.KycCertInfo;
import com.vcc.data.entity.KycSuccessCertInfo;
import com.vcc.data.mapper.KycCertInfoMapper;
import com.vcc.service.boss.request.kyc.AuditKycDto;
import com.vcc.service.boss.response.kyc.KycCertInfoVoBoss;
import com.vcc.service.client.dto.kyc.KycCertInfoDto;
import com.vcc.service.client.vo.kyc.KycCertInfoVo;
import com.vcc.service.sa.BossUserUtil;
import com.vcc.service.service.KycCertInfoService;
import com.vcc.service.service.KycSuccessCertInfoService;
import com.vcc.service.service.UserService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.Date;

import static com.vcc.data.entity.table.BossUserTableDef.BOSS_USER;
import static com.vcc.data.entity.table.KycCertInfoTableDef.KYC_CERT_INFO;
import static com.vcc.data.entity.table.UserTableDef.USER;

@Service
public class KycCertInfoServiceImpl extends ServiceImpl<KycCertInfoMapper, KycCertInfo> implements KycCertInfoService {

    @Resource
    private KycSuccessCertInfoService kycSuccessCertInfoService;
    @Resource
    private UserService userService;

    @Override
    public Boolean existsByUserId(Long userId) {
        return queryChain().eq(KycCertInfo::getUserId, userId).exists();
    }

    @Override
    public KycCertInfoVo getByUserId(Long userId) {
        QueryChain<KycCertInfo> queryChain = queryChain().eq(KycCertInfo::getUserId, userId);
        queryChain.leftJoin(USER).on(USER.ID.eq(KYC_CERT_INFO.USER_ID));
        queryChain.select(
                KYC_CERT_INFO.ALL_COLUMNS,
                USER.EMAIL.as("account")
        );
        return queryChain.oneAsOpt(KycCertInfoVo.class).orElseThrow(() -> new NotFoundException("并未提交认证"));
    }

    @Override
    public Boolean requestCert(KycCertInfoDto kycCertInfoDto, Long userId) {
        //只有认证失败和成功的情况下可以重新提交认证
        if (existsByUserId(userId)) {
            KycCertInfoVo kycCertInfo = getByUserId(userId);
            if (kycCertInfo.getStatus() == 2) {
                throw new ProgramException("认证正在审核中");
            }
            if (kycCertInfo.getStatus() == 0) {
                throw new ProgramException("认证已通过，不能重复提交");
            }
            removeById(kycCertInfo.getId());
        }
        KycCertInfo kycCertInfo = new KycCertInfo();
        kycCertInfo.setCertType(kycCertInfoDto.getCertType());
        kycCertInfo.setHasLongTerm(kycCertInfoDto.getHasLongTerm());
        kycCertInfo.setCertExpireDate(kycCertInfoDto.getCertExpireDate());
        kycCertInfo.setGender(kycCertInfoDto.getGender());
        kycCertInfo.setEmail(kycCertInfoDto.getEmail());
        kycCertInfo.setCertNo(kycCertInfoDto.getCertNo());
        kycCertInfo.setFirstName(kycCertInfoDto.getFirstName());
        kycCertInfo.setLastName(kycCertInfoDto.getLastName());
        kycCertInfo.setCountry(kycCertInfoDto.getCountry());
        kycCertInfo.setCertAddress(kycCertInfoDto.getCertAddress());
        kycCertInfo.setBirthday(kycCertInfoDto.getBirthday());
        kycCertInfo.setCertImgFront(kycCertInfoDto.getCertImgFront());
        kycCertInfo.setCertImgBack(kycCertInfoDto.getCertImgBack());
        kycCertInfo.setCertImgHand(kycCertInfoDto.getCertImgHand());
        kycCertInfo.setDwellAddress(kycCertInfoDto.getDwellAddress());
        kycCertInfo.setDwellPostCode(kycCertInfoDto.getDwellPostCode());
        kycCertInfo.setUserId(userId);
        kycCertInfo.setStatus(2);
        kycCertInfo.setRequestDate(new Date());
        save(kycCertInfo);
        return true;
    }

    @Override
    public Page<KycCertInfoVoBoss> paging(Page<KycCertInfoVoBoss> pageable, Integer status, String certName, Long targetUserId) {
        QueryChain<KycCertInfo> queryChain = queryChain();
        queryChain.leftJoin(USER).on(USER.ID.eq(KYC_CERT_INFO.USER_ID));
        queryChain.select(
                KYC_CERT_INFO.ALL_COLUMNS,
                USER.EMAIL.as("account")
        );
        Long bossUserId = BossUserUtil.getIdNotNull();
        if (!BossUserUtil.hasAllData()) {
            queryChain.leftJoin(BOSS_USER.as("dealer")).on(USER.BE_LONG_TO_DEALER.eq(BOSS_USER.ID));
            queryChain.and(
                    BOSS_USER.as("dealer").ID.eq(bossUserId)
                            .or(BOSS_USER.as("dealer").PARENT_ID.eq(bossUserId))
            );
        }
        if (RegexUtil.checkObjectIsNotNull(status)) {
            queryChain.eq(KycCertInfo::getStatus, status);
        }
        if (RegexUtil.checkStringIsNotNull(certName)) {
            queryChain.like(KycCertInfo::getFirstName, certName);
        }
        if (RegexUtil.checkObjectIsNotNull(targetUserId)) {
            queryChain.eq(KycCertInfo::getUserId, targetUserId);
        }
        queryChain.orderBy(KycCertInfo::getRequestDate, false);
        return queryChain.pageAs(pageable, KycCertInfoVoBoss.class);
    }

    @Override
    public Boolean audit(AuditKycDto auditKycDto) {
        KycCertInfo kycCertInfo = queryChain().eq(KycCertInfo::getId, auditKycDto.getId()).eq(KycCertInfo::getStatus, 2).oneOpt().orElseThrow(() -> new NotFoundException("认证信息不存在或已审核"));
        Long dealerId = userService.getDealerIdById(kycCertInfo.getUserId());
        if (!BossUserUtil.hasAllData() && !dealerId.equals(BossUserUtil.getId())) {
            throw new ProgramException("无权操作用户的参数配置");
        }
        if (auditKycDto.getStatus()) {
            updateChain()
                    .eq(KycCertInfo::getId, auditKycDto.getId())
                    .set(KycCertInfo::getStatus, 0)
                    .set(KycCertInfo::getAuditDate, new Date())
                    .set(KycCertInfo::getAuditUserId, dealerId)
                    .set(KycCertInfo::getAuditRemark, "审核通过:" + (RegexUtil.checkStringIsNull(auditKycDto.getRemark()) ? "" : auditKycDto.getRemark()))
                    .update();
            KycSuccessCertInfo kycSuccessCertInfo = new KycSuccessCertInfo();
            kycSuccessCertInfo.setCertType(kycCertInfo.getCertType());
            kycSuccessCertInfo.setHasLongTerm(kycCertInfo.getHasLongTerm());
            kycSuccessCertInfo.setCertExpireDate(kycCertInfo.getCertExpireDate());
            kycSuccessCertInfo.setGender(kycCertInfo.getGender());
            kycSuccessCertInfo.setEmail(kycCertInfo.getEmail());
            kycSuccessCertInfo.setFirstName(kycSuccessCertInfo.getFirstName());
            kycSuccessCertInfo.setLastName(kycSuccessCertInfo.getLastName());
            kycSuccessCertInfo.setCountry(kycCertInfo.getCountry());
            kycSuccessCertInfo.setDwellAddress(kycCertInfo.getDwellAddress());
            kycSuccessCertInfo.setDwellPostCode(kycCertInfo.getDwellPostCode());
            kycSuccessCertInfo.setUserId(kycCertInfo.getUserId());
            kycSuccessCertInfo.setCertNo(kycCertInfo.getCertNo());
            kycSuccessCertInfo.setCertType(kycCertInfo.getCertType());
            kycSuccessCertInfo.setCertAddress(kycCertInfo.getCertAddress());
            kycSuccessCertInfo.setBirthday(kycCertInfo.getBirthday());
            kycSuccessCertInfo.setCertImgFront(kycCertInfo.getCertImgFront());
            kycSuccessCertInfo.setCertImgBack(kycCertInfo.getCertImgBack());
            kycSuccessCertInfo.setCertImgHand(kycCertInfo.getCertImgHand());
            kycSuccessCertInfo.setAuditDate(new Date());
            kycSuccessCertInfo.setRequestDate(kycCertInfo.getRequestDate());
            kycSuccessCertInfo.setAuditRemark("审核通过:" + (RegexUtil.checkStringIsNull(auditKycDto.getRemark()) ? "" : auditKycDto.getRemark()));
            kycSuccessCertInfo.setAuditUserId(dealerId);
            kycSuccessCertInfo.setStatus(0);
            kycSuccessCertInfo.setCount(1);
            kycSuccessCertInfoService.save(kycSuccessCertInfo);
        } else {
            updateChain()
                    .eq(KycCertInfo::getId, auditKycDto.getId())
                    .set(KycCertInfo::getStatus, 1)
                    .set(KycCertInfo::getAuditDate, new Date())
                    .set(KycCertInfo::getAuditUserId, dealerId)
                    .set(KycCertInfo::getAuditRemark, "审核不通过:" + (RegexUtil.checkStringIsNull(auditKycDto.getRemark()) ? "" : auditKycDto.getRemark()))
                    .update();
        }
        return true;
    }

    @Override
    public Boolean removeByUserId(Long userId) {
        try {
            KycCertInfoVo certInfoVo = getByUserId(userId);
            if (certInfoVo.getStatus() == 0) {
                throw new ProgramException("认证已通过，不能删除");
            }
            return removeById(certInfoVo.getId());
        } catch (NotFoundException e) {
            return true;
        }
    }
}
